<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha256-AbA177XfpSnFEvgpYu1jMygiLabzPCJCRIBtR5jGc0k=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"fengxun2017.github.io","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.13.2","exturl":false,"sidebar":{"position":"right","display":"hide","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>

    <meta name="description" content="lwip ip层处理逻辑梳理（IPV4）">
<meta property="og:type" content="article">
<meta property="og:title" content="lwip ip层处理逻辑梳理">
<meta property="og:url" content="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/index.html">
<meta property="og:site_name" content="fx">
<meta property="og:description" content="lwip ip层处理逻辑梳理（IPV4）">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/ipv4-header.png">
<meta property="article:published_time" content="2025-09-23T16:00:00.000Z">
<meta property="article:modified_time" content="2025-09-24T01:00:01.292Z">
<meta property="article:author" content="feng xun">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/ipv4-header.png">


<link rel="canonical" href="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/","path":"2025/09/24/TCPIP-lwip-ipinput/","title":"lwip ip层处理逻辑梳理"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>lwip ip层处理逻辑梳理 | fx</title>
  






  <script async defer data-website-id="" src=""></script>

  <script defer data-domain="" src=""></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
  <a target="_blank" rel="noopener" href="https://github.com/fengxun2017" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#70B7FD; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">fx</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">FreeRTOS交流QQ群-663806972 BLE学习交流群-498676838</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
  </ul>
</nav>




</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%98%B6%E6%AE%B5-1-%E5%88%9D%E5%A7%8B%E6%A3%80%E6%9F%A5%E5%92%8C%E5%AE%8C%E6%95%B4%E6%80%A7%E9%AA%8C%E8%AF%81-Validation"><span class="nav-number">1.</span> <span class="nav-text">阶段 1: 初始检查和完整性验证 (Validation)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%98%B6%E6%AE%B5-2-%E5%8C%85%E7%9A%84%E7%9B%AE%E7%9A%84%E5%9C%B0%E5%88%A4%E6%96%AD-Destination-Decision"><span class="nav-number">2.</span> <span class="nav-text">阶段 2: 包的目的地判断 (Destination Decision)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%98%B6%E6%AE%B5-3-%E9%A2%84%E5%A4%84%E7%90%86%E4%B8%8E%E5%88%86%E7%89%87%E9%87%8D%E7%BB%84-Preprocessing-amp-Reassembly"><span class="nav-number">3.</span> <span class="nav-text">阶段 3: 预处理与分片重组 (Preprocessing &amp; Reassembly)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%98%B6%E6%AE%B5-4-%E5%90%91%E4%B8%8A%E5%B1%82%E5%8D%8F%E8%AE%AE%E5%88%86%E5%8F%91-Demultiplexing-to-Transport-Layer"><span class="nav-number">4.</span> <span class="nav-text">阶段 4: 向上层协议分发 (Demultiplexing to Transport Layer)</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">feng xun</p>
  <div class="site-description" itemprop="description">FreeRTOS交流QQ群-663806972 BLE学习交流群-498676838</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">96</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">16</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
  </nav>
</div>
  <div class="cc-license site-overview-item animated" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" class="cc-opacity" rel="noopener" target="_blank"><img src="https://cdnjs.cloudflare.com/ajax/libs/creativecommons-vocabulary/2020.11.3/assets/license_badges/small/by_nc_sa.svg" alt="Creative Commons"></a>
  </div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="feng xun">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="fx">
      <meta itemprop="description" content="FreeRTOS交流QQ群-663806972 BLE学习交流群-498676838">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="lwip ip层处理逻辑梳理 | fx">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          lwip ip层处理逻辑梳理
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2025-09-24 00:00:00" itemprop="dateCreated datePublished" datetime="2025-09-24T00:00:00+08:00">2025-09-24</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/TCP-IP/" itemprop="url" rel="index"><span itemprop="name">TCP/IP</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>4.7k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>6 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <center>
lwip ip层处理逻辑梳理（IPV4）
</center>

<span id="more"></span>

<hr>
<p>ip4_input 核心处理流程如下图所示：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">flowchart TD</span><br><span class="line">A[&quot;ip4_input(pbuf p, netif inp)&quot;] --&gt; B[&quot;初始检查&lt;br&gt;版本号、长度、校验和&quot;];</span><br><span class="line">B --&gt; C&#123;&quot;目的地址是&lt;br&gt;本机地址?&quot;&#125;;</span><br><span class="line">C -- Yes --&gt; D[标记netif为本机];</span><br><span class="line">C -- No --&gt; E&#123;&quot;启用IP_FORWARD&lt;br&gt;且是单播包?&quot;&#125;;</span><br><span class="line">E -- Yes --&gt; F[&quot;ip4_forward()&lt;br&gt;转发包&quot;];</span><br><span class="line">E -- No --&gt; G[丢弃包];</span><br><span class="line"></span><br><span class="line">subgraph C[目的地址判断逻辑]</span><br><span class="line">    C1[&quot;多播地址?&quot;] -- Yes --&gt; C2[&quot;IGMP Snooping或&lt;br&gt;接口已启动?&quot;];</span><br><span class="line">    C1 -- No --&gt; C3[&quot;单播地址?&quot;] -- Yes --&gt; C4[&quot;ip4_input_accept(inp)&lt;br&gt;检查接口IP匹配?&quot;];</span><br><span class="line">    C4 -- No --&gt; C5[&quot;遍历所有netif&lt;br&gt;寻找匹配接口&quot;];</span><br><span class="line">    C2 -- Yes --&gt; D;</span><br><span class="line">    C2 -- No --&gt; Z[丢弃包];</span><br><span class="line">    C4 -- Yes --&gt; D;</span><br><span class="line">    C5 -- Found --&gt; D;</span><br><span class="line">    C5 -- Not Found --&gt; E;</span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">D --&gt; H&#123;&quot;包有分片标志?&quot;&#125;;</span><br><span class="line">H -- Yes --&gt; I[&quot;ip4_reass()&lt;br&gt;尝试重组&quot;];</span><br><span class="line">I -- 重组未完成 --&gt; Z[&quot;释放pbuf, return&quot;];</span><br><span class="line">I -- 重组成功 --&gt; J;</span><br><span class="line">H -- No --&gt; J[&quot;检查是否有IP选项(如果宏打开了禁止IP选项)&quot;];</span><br><span class="line"></span><br><span class="line">J --&gt; K[&quot;剥离IP头部&lt;br&gt;pbuf_remove_header()&quot;];</span><br><span class="line">K --&gt; L[&quot;根据IP头协议字段&lt;br&gt;分发给上层协议&quot;];</span><br><span class="line">L --&gt; M[&quot;UDP?&quot;] --&gt; N[&quot;udp_input()&quot;];</span><br><span class="line">L --&gt; O[&quot;TCP?&quot;] --&gt; P[&quot;tcp_input()&quot;];</span><br><span class="line">L --&gt; Q[&quot;ICMP?&quot;] --&gt; R[&quot;icmp_input()&quot;];</span><br><span class="line">L --&gt; S[&quot;其他协议&quot;] --&gt; T[&quot;发送ICMP不可达或丢弃&quot;];</span><br><span class="line"></span><br><span class="line">N &amp; P &amp; R --&gt; U[&quot;清理全局变量&quot;];</span><br><span class="line">U --&gt; V[&quot;return ERR_OK&quot;];</span><br><span class="line">Z --&gt; V;</span><br></pre></td></tr></table></figure>


<p>IPV4帧头结构：<br><img src="/2025/09/24/TCPIP-lwip-ipinput/ipv4-header.png"></p>
<h3 id="阶段-1-初始检查和完整性验证-Validation"><a href="#阶段-1-初始检查和完整性验证-Validation" class="headerlink" title="阶段 1: 初始检查和完整性验证 (Validation)"></a>阶段 1: 初始检查和完整性验证 (Validation)</h3><p><strong>统计与断言</strong>:</p>
<ul>
<li>IP_STATS_INC(ip.recv): 增加IP包接收统计计数器。</li>
<li>LWIP_ASSERT_CORE_LOCKED(): 确保核心锁已持有，保证多线程安全。</li>
<li>MIB2_STATS_INC(mib2.ipinreceives): 增加MIB2标准统计信息。</li>
</ul>
<p><strong>版本号检查</strong>:</p>
<ul>
<li>if (IPH_V(iphdr) !&#x3D; 4): 检查IP版本号是否为4。如果不是，打印调试信息、释放包并增加错误计数。</li>
</ul>
<p><strong>长度检查</strong>:</p>
<ul>
<li>获取首部长度: iphdr_hlen &#x3D; IPH_HL_BYTES(iphdr) （IHL字段 x 4）。</li>
<li>获取总长度: iphdr_len &#x3D; lwip_ntohs(IPH_LEN(iphdr))。</li>
<li>修剪 pbuf: pbuf_realloc(p, iphdr_len) 确保 p-&gt;tot_len 不大于IP包总长度，<strong>处理可能存在的链路层填充</strong> (半双工以太网链路层最小帧长64字节)。</li>
</ul>
<p><strong>全面长度校验: 检查是否满足：</strong></p>
<ul>
<li>(iphdr_hlen &gt;&#x3D; IP_HLEN) （首部长度至少20字节）</li>
<li>(iphdr_hlen &lt;&#x3D; p-&gt;len) （处理逻辑中直接将第一个pbuf的数据强转为ip帧头struct ip_hdr，因此首部必须完全在第一个pbuf内）</li>
<li>(iphdr_len &lt;&#x3D; p-&gt;tot_len) （IP包总长度不能大于pbuf总长度）</li>
<li>任何一项失败都意味着包损坏，会被丢弃。</li>
</ul>
<p><strong>校验和验证</strong>:<br>#if CHECKSUM_CHECK_IP: 如果使能了IP校验和检查，则计算首部校验和并与包中的值对比。如果校验失败，包被丢弃。（许多现代硬件在网卡中完成此操作，软件校验可能被禁用。）</p>
<p><strong>复制地址</strong>:<br>ip_addr_copy_from_ip4(…)：将IP头中的源和目的地址（可能是非对齐的）复制到对齐的全局变量 ip_data.current_iphdr_src&#x2F;dest 中，便于后续访问。</p>
<ul>
<li>LWIP通过使用特殊的类型定义和编译器指令（packed）来确保即使IP头中的地址非对齐，也能通过多次字节访问（而不是一次32位访问）来安全地读取它。</li>
<li>当编译器遇到一个打包结构体时，它知道访问其成员可能会遇到非对齐地址。因此，编译器会自动生成能够安全处理非对齐内存访问的代码。</li>
<li>这个拷贝是一次性的开销，目的是为了将数据从“需要特殊方式访问”的非对齐位置，移动到一个“可以常规快速访问”的对齐位置。</li>
<li>将IP地址从可能被后续处理（如分片重组）修改或释放的 pbuf 中提取出来，存入稳定的全局上下文 ip_data 中，确保其在整个处理流程中可以被高效使用。</li>
</ul>
<h3 id="阶段-2-包的目的地判断-Destination-Decision"><a href="#阶段-2-包的目的地判断-Destination-Decision" class="headerlink" title="阶段 2: 包的目的地判断 (Destination Decision)"></a>阶段 2: 包的目的地判断 (Destination Decision)</h3><p>这是路由决策的核心环节，用于确定这个包是否是发给本机的。</p>
<p><strong>处理多播包</strong> (ip4_addr_ismulticast)：如果目的地址是多播地址：</p>
<ul>
<li><p>如果使能了IGMP (LWIP_IGMP)：</p>
<ul>
<li>如果接口属于该多播组 (igmp_lookfor_group)，且目的地址为224.0.0.1，源地址为0.0.0.0，授予豁免权（check_ip_src&#x3D;0），后续的检查会允许这个“非法”源地址的包通过。（这里特殊处理 224.0.0.1目的地址和 0.0.0.0 源地址。是为了兼容实现了 RFC 4541 标准的 IGMP Snooping 交换机，特许接收那些由交换机生成的、源地址为 0.0.0.0 且发往“所有系统”地址 (224.0.0.1) 的 IGMP 成员报告报文。如果没有这段代码，根据常规的源地址检查规则，这种报文会被视为非法而丢弃。这会导致 IGMP Snooping 交换机无法正常学习组播成员关系，进而破坏整个网络的多播流量优化。）</li>
</ul>
</li>
<li><p>如果未使能IGMP：只要接口已启动且配置了IP地址，就接受该多播包。</p>
</li>
</ul>
<p><strong>处理单播&#x2F;广播包</strong>:</p>
<p><strong>第一步</strong>: 检查接收接口 inp 是否应该接受此包 (ip4_input_accept(inp))。这个函数检查：</p>
<ul>
<li>接口是否启动 (netif_is_up)。</li>
<li>接口是否配置了IP地址 (!ip4_addr_isany)。</li>
<li>包的目的IP是否与接口的IP地址或广播地址或子网广播地址匹配。</li>
</ul>
<p><strong>第二步</strong>: 如果 inp 不匹配，则遍历所有网络接口 (NETIF_FOREACH)，寻找一个匹配的接口。</p>
<p><strong>特殊处理</strong> (链路层寻址，IP_ACCEPT_LINK_LAYER_ADDRESSING):DHCP 处理，即使目的IP不是本机（例如客户端尚未获取IP，目的可能是 255.255.255.255），如果包是发往DHCP客户端端口（67&#x2F;68）的UDP包，则仍然接受它，豁免ip源地址检查。这是符合RFC标准的。</p>
<p><strong>源地址合法性检查</strong>:检查源IP地址不能是广播或多播地址，防止IP欺骗。DHCP服务器发来的包（源地址为 0.0.0.0）是特例。</p>
<p><strong>最终决定</strong>:经过以上所有步骤</p>
<ul>
<li>如果 netif &#x3D;&#x3D; NULL，说明没有接口认领这个包，即它不是发给我们的。该条件下，如果使能了转发 (IP_FORWARD) 且不是广播包：调用 ip4_forward(p, iphdr, inp) 尝试将包转发到其他网络。否则：直接丢弃包，更新统计信息。</li>
<li>否则，继续执行下面流程</li>
</ul>
<h3 id="阶段-3-预处理与分片重组-Preprocessing-amp-Reassembly"><a href="#阶段-3-预处理与分片重组-Preprocessing-amp-Reassembly" class="headerlink" title="阶段 3: 预处理与分片重组 (Preprocessing &amp; Reassembly)"></a>阶段 3: 预处理与分片重组 (Preprocessing &amp; Reassembly)</h3><p>检查分片标志: if ((IPH_OFFSET(iphdr) &amp; PP_HTONS(IP_OFFMASK | IP_MF)) !&#x3D; 0) </p>
<p>如果使能了重组 (IP_REASSEMBLY)：调用 p &#x3D; ip4_reass(p) 尝试将所有分片重组为一个完整的IP数据包。</p>
<ul>
<li>如果重组未完成（返回 NULL），则直接返回。</li>
<li>如果重组成功，需要重新获取 iphdr 指针。</li>
</ul>
<p>如果未使能重组：直接丢弃分片包，并增加错误统计。</p>
<p>IP选项检查:</p>
<ul>
<li>如果禁止了IP选项 (IP_OPTIONS_ALLOWED &#x3D;&#x3D; 0)：检查首部长度是否大于20字节。如果是，且不是IGMP报文（IGMP包含合法的“路由器警告”选项），则丢弃包。这是一个简化处理，用于资源极度受限的系统。</li>
</ul>
<h3 id="阶段-4-向上层协议分发-Demultiplexing-to-Transport-Layer"><a href="#阶段-4-向上层协议分发-Demultiplexing-to-Transport-Layer" class="headerlink" title="阶段 4: 向上层协议分发 (Demultiplexing to Transport Layer)"></a>阶段 4: 向上层协议分发 (Demultiplexing to Transport Layer)</h3><p>设置全局上下文:<br>  ip_data.current_netif &#x3D; netif;<br>  ip_data.current_input_netif &#x3D; inp;<br>  ip_data.current_ip4_header &#x3D; iphdr;<br>  ip_data.current_ip_header_tot_len &#x3D; IPH_HL_BYTES(iphdr);<br>将当前处理的网络接口、IP头等信息设置到 ip_data 全局结构中，供上层协议输入函数使用。</p>
<p>Raw PCB 处理: #if LWIP_RAW：首先调用 raw_input(p, inp)。</p>
<ul>
<li>如果任何原始套接字“吃掉”了这个包 (RAW_INPUT_EATEN)，则跳过后续处理。</li>
<li>否则，继续后续处理流程</li>
</ul>
<p>移除IP首部:pbuf_remove_header(p, iphdr_hlen): 调整 pbuf 的 payload 指针，使其指向 传输层首部（如TCP头、UDP头），为上层处理做准备。</p>
<p>协议分发 (switch (IPH_PROTO(iphdr)))，根据IP头中的 Protocol 字段，将包分发给相应的上层协议输入函数：</p>
<ul>
<li>UDP (IP_PROTO_UDP) -&gt; udp_input(p, inp)</li>
<li>TCP (IP_PROTO_TCP) -&gt; tcp_input(p, inp)</li>
<li>ICMP (IP_PROTO_ICMP) -&gt; icmp_input(p, inp)</li>
<li>IGMP (IP_PROTO_IGMP) -&gt; igmp_input(p, inp, …)</li>
</ul>
<p>对于不支持的协议：如果不是广播&#x2F;多播包，则发送一个 ICMP 目的地不可达（协议不可达） 报文给源主机。</p>
<p>丢弃包并更新统计信息。</p>
<p>清理:清理全局变量 ip_data 中的当前状态，避免后续处理产生混淆。</p>

    </div>

    
    
    

    <footer class="post-footer">
          

<div class="post-copyright">
<ul>
  <li class="post-copyright-author">
      <strong>本文作者： </strong>feng xun
  </li>
  <li class="post-copyright-link">
      <strong>本文链接：</strong>
      <a href="http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/" title="lwip ip层处理逻辑梳理">http://fengxun2017.github.io/2025/09/24/TCPIP-lwip-ipinput/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>


        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2025/09/14/Arm%20cortex-m%20Fault%20Exceptions/" rel="prev" title="ARM Cortex-m Fault Exceptions 文档学习">
                  <i class="fa fa-chevron-left"></i> ARM Cortex-m Fault Exceptions 文档学习
                </a>
            </div>
            <div class="post-nav-item">
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2025</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">feng xun</span>
</div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">552k</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">11:30</span>
  </span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
